#include "DatReader.h"
#include <charconv>
#include <fstream>

DatReader::DatReader(){}

vector<ResultData> DatReader::load(const string& filePath, const int NCells) {
    this->path = filePath;
    this->resultData.reserve(NCells);

    // 打开文件并获取大小
    std::ifstream file(path, std::ios::ate | std::ios::binary);
    fileSize = file.tellg();
    file.seekg(0);
    
    // 将整个文件读入内存缓冲区
    fileData = std::make_unique<char[]>(fileSize);
    file.read(fileData.get(), fileSize);
    
    // 处理首行
    const char* p = fileData.get();
    while (*p++ != '\n'); // 跳过标题行
    
    // 解析数据主体部分
    parse(p, fileData.get() + fileSize);
    return resultData;
}

void DatReader::parse(const char* start, const char* end) {
    resultData.clear();
    
    ResultData dp;  // 临时数据存储对象
    const char* p = start;
    
    // 逐行解析数据
    while (p < end) {
        // 按顺序解析8个数据字段
        p = parseField(p, dp.x);            // X坐标
        p = parseField(++p, dp.y);          // Y坐标 
        p = parseField(++p, dp.z);          // Z
        p = parseField(++p, dp.zb);         // ZB
        p = parseField(++p, dp.u);          // U方向分量
        p = parseField(++p, dp.v);          // V方向分量
        p = parseField(++p, dp.flag);       // 状态标志
        p = parseField(++p, dp.Total_In);   // 总入流
        
        resultData.push_back(dp);
        
        // 移动到下一行起始位置
        while (*p != '\n' && p < end) ++p; // 跳过行尾可能的多余字符
        ++p; // 跳过换行符
    }
}

const char* DatReader::parseField(const char* p, double& res) {
    auto [ptr, ec] = std::from_chars(p, p + 64, res);
    return ptr;
}